/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package SemanticoPacote;

import SemanticoPacote.TratamentoErroSemantico.ErroSemantico;
import compilador_full.TabelaSimbolos;

/**
 *
 * @author Larissa Rocha Soares
 */
public class declaraVariaveis
{
    private TabelaSimbolos tabelaSimbolos;


    public void declaraVariaveis(TabelaSimbolos tabelaSimbolos, String metodo)
    {

        if(tabelaSimbolos.getLookahead().equals("typedef")) // se tiver o typedef
            tabelaSimbolos.soConsome();//Consome Typedef
        
        String tipo = tabelaSimbolos.getLookahead();//Guarda o tipo da variável
        tabelaSimbolos.soConsome();//Consome Tipo
        

        if(tabelaSimbolos.getTipo().equals("identificador"))
        {
            if (metodo.equals("global")){

                if(tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead())){
                    if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())){
                        System.out.println("Linha "+ tabelaSimbolos.getLinha() +":" + " A Variavel " + tabelaSimbolos.getLookahead() +
                            " já foi declarada entre as globais");
                        ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada");
                    }
                }
            }

            else
            {

//            if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())&&tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead()))
//                System.out.println("Ela já é global");
//            else if(tabelaSimbolos.jaContemAquelaVariavel(tabelaSimbolos.getLookahead()))
//                System.out.println("Já existe essa variável declarada");


            //Analisa se a variável ja foi declarada dentro do método. Se existe duas váriasveis com o mesmo nome.
                if(!(tabelaSimbolos.verificaMetodoEMetodo(tabelaSimbolos.getLookahead(), metodo)))
                {
                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " + "A variável " + tabelaSimbolos.getLookahead() +
                            " foi declarada mais de uma vez no metodo " + metodo);
                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada");
                }
            //Verifica se a variavel, que esta declarada em um método, ja foi declarada como global.
                if(!(tabelaSimbolos.verificaMetodoEGlobal(tabelaSimbolos.getLookahead()))){
                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                            " declarada no método " + metodo + " também foi declarada como global" );
                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável foi declarada como global");

                }
            }
        
                
        tabelaSimbolos.soConsome();//Consome identificador
        }

        else if(tabelaSimbolos.getLookahead().equals("*"))
        {
            tabelaSimbolos.soConsome();//Consome o *
            
            //if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())&&tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead()))
            //    System.out.println("Ela já é global");
            //else if(tabelaSimbolos.jaContemAquelaVariavel(tabelaSimbolos.getLookahead()))
            //    System.out.println("Já existe essa variável declarada");
            if (metodo.equals("global")){

                if(tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead())){
                    if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())){
                        System.out.println("Linha "+ tabelaSimbolos.getLinha() +":" + " A Variavel " + tabelaSimbolos.getLookahead() +
                            " já foi declarada entre as globais");
                        ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                    }
                }
            }
            else
            {
            //Analisa se a variável ja foi declarada dentro do método. Se existe duas váriasveis com o mesmo nome.
                if(!(tabelaSimbolos.verificaMetodoEMetodo(tabelaSimbolos.getLookahead(), metodo)))
                {
                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                            "foi declarada mais de uma vez no metodo " + metodo);
                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada no método");
                }
            //Verifica se a variavel, que esta declarada em um método, ja foi declarada como global.
                if(!(tabelaSimbolos.verificaMetodoEGlobal(tabelaSimbolos.getLookahead()))){
                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                            " declarada no método " + metodo + " também foi declarada como global" );
                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                }
            }
            
            tabelaSimbolos.soConsome();//Consome o identificador
        }        

        while(!tabelaSimbolos.getLookahead().equals(";"))
        {
            if(tabelaSimbolos.getLookahead().equals("="))
            {
                tabelaSimbolos.soConsome();//Consome igual
                if(!Utils.tipoValor(tabelaSimbolos.getLookahead()).equals(tipo))
                {
                    System.out.println("Tipos não compatíveis");
                     ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Tipos não compatíveis");
                }
                tabelaSimbolos.soConsome();//Consome o que vem depois do igual
                if(tabelaSimbolos.getLookahead().equals(","))
                {
                    while(tabelaSimbolos.getLookahead().equals(","))
                    {
                        tabelaSimbolos.soConsome();//Consume a vírgula
                        
                        if(tabelaSimbolos.getTipo().equals("identificador"))
                        {           
//                            if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())&&tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead()))
//                                System.out.println("Ela já é global");
//                            else if(tabelaSimbolos.jaContemAquelaVariavel(tabelaSimbolos.getLookahead()))
//                                System.out.println("Já existe essa variável declarada");
                            if (metodo.equals("global")){

                                if(tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead())){
                                    if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())){
                                        System.out.println("Linha "+ tabelaSimbolos.getLinha() +":" + " A Variavel " + tabelaSimbolos.getLookahead() +
                                                            " já foi declarada entre as globais");
                                        ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada entre as globais");
                                    }
                                }
                            }
                            else
                            {
                            //Analisa se a variável ja foi declarada dentro do método. Se existe duas váriasveis com o mesmo nome.
                                if(!(tabelaSimbolos.verificaMetodoEMetodo(tabelaSimbolos.getLookahead(), metodo)))
                                {
                                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                                            "foi declarada mais de uma vez no metodo " + metodo);
                                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada");
                                }
                            //Verifica se a variavel, que esta declarada em um método, ja foi declarada como global.
                                if(!(tabelaSimbolos.verificaMetodoEGlobal(tabelaSimbolos.getLookahead()))){
                                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                                                        " declarada no método " + metodo + " também foi declarada como global" );
                                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                                }
                            }
                            tabelaSimbolos.soConsome();//Consome identificador

                            if(tabelaSimbolos.getLookahead().equals("["))
                            {
                                if(!casoVetor())
                                {
                                    System.out.println("Deve ter um int entre [ ]");
                                     ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Deve haver um inteiro entre [ ]");
                                    tabelaSimbolos.soConsome();//Consome o que tem dentro do []
                                    tabelaSimbolos.soConsome();//Consome ]
                                }
                            }
                        }
                        else if(tabelaSimbolos.getLookahead().equals("*"))
                        {
                            tabelaSimbolos.soConsome();//Consome o *

//                            if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())&&tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead()))
//                                System.out.println("Ela já é global");
//                            else if(tabelaSimbolos.jaContemAquelaVariavel(tabelaSimbolos.getLookahead()))
//                                System.out.println("Já existe essa variável declarada");
                            if (metodo.equals("global")){

                                if(tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead())){
                                    if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())){
                                        System.out.println("Linha "+ tabelaSimbolos.getLinha() +":" + " A Variavel " + tabelaSimbolos.getLookahead() +
                                                            " já foi declarada entre as globais");
                                        ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                                    }
                                }
                            }
                            else
                            {
                            //Analisa se a variável ja foi declarada dentro do método. Se existe duas váriasveis com o mesmo nome.
                                if(!(tabelaSimbolos.verificaMetodoEMetodo(tabelaSimbolos.getLookahead(), metodo)))
                                {
                                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                                            "foi declarada mais de uma vez no metodo " + metodo);
                                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada");
                                }
                            //Verifica se a variavel, que esta declarada em um método, ja foi declarada como global.
                                if(!(tabelaSimbolos.verificaMetodoEGlobal(tabelaSimbolos.getLookahead()))){
                                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                                                        " declarada no método " + metodo + " também foi declarada como global" );
                                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                                }
                            }

                            tabelaSimbolos.soConsome();//Consome o identificador
                        }
                        
                        if(tabelaSimbolos.getLookahead().equals("="))
                        {
                            if(!Utils.tipoValor(tabelaSimbolos.getLookahead()).equals(tipo))
                            {
                                System.out.println("Tipos não compatíveis");
                                ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Tipos não compatíveis");
                            }
                        }
                    }
                }
            }
            else if(tabelaSimbolos.getLookahead().equals("["))
            {
                if(!casoVetor())
                {
                    System.out.println("Deve ter um int entre [ ]");
                    tabelaSimbolos.soConsome();//Consome o que tem dentro do []
                    tabelaSimbolos.soConsome();//Consome ]
                }
            }
            else if(tabelaSimbolos.getLookahead().equals(","))
            {
                while(tabelaSimbolos.getLookahead().equals(","))
                {
                    tabelaSimbolos.soConsome();//Consume a vírgula
                    
                    if(tabelaSimbolos.getTipo().equals("identificador"))
                    {
//                        if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())&&tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead()))
//                            System.out.println("Ela já é global");
//                        else if(tabelaSimbolos.jaContemAquelaVariavel(tabelaSimbolos.getLookahead()))
//                            System.out.println("Já existe essa variável declarada");
                        
                        if (metodo.equals("global")){

                            if(tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead())){
                                 if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())){
                                    System.out.println("Linha "+ tabelaSimbolos.getLinha() +":" + " A Variavel " + tabelaSimbolos.getLookahead() +
                                     " já foi declarada entre as globais");
                                    ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                                 }
                            }
                        }


                        else
                        {
                        //Analisa se a variável ja foi declarada dentro do método. Se existe duas váriasveis com o mesmo nome.
                            if(!(tabelaSimbolos.verificaMetodoEMetodo(tabelaSimbolos.getLookahead(), metodo)))
                            {
                                System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                                        "foi declarada mais de uma vez no metodo " + metodo);
                                ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada");
                            }
                        //Verifica se a variavel, que esta declarada em um método, ja foi declarada como global.
                            if(!(tabelaSimbolos.verificaMetodoEGlobal(tabelaSimbolos.getLookahead()))){
                                System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                                                    " declarada no método " + metodo + " também foi declarada como global" );
                                ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                            }
                        }

                        tabelaSimbolos.soConsome();//Consome identificador


                        if(tabelaSimbolos.getLookahead().equals("["))
                        {
                            if(!casoVetor())
                            {
                                System.out.println("Deve ter um int entre [ ]");
                                tabelaSimbolos.soConsome();//Consome o que tem dentro do []
                                tabelaSimbolos.soConsome();//Consome ]
                            }
                        }
                    }
                    else if(tabelaSimbolos.getLookahead().equals("*"))
                    {
                        tabelaSimbolos.soConsome();//Consome o *

//                        if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())&&tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead()))
//                            System.out.println("Ela já é global");
//                        else if(tabelaSimbolos.jaContemAquelaVariavel(tabelaSimbolos.getLookahead()))
//                            System.out.println("Já existe essa variável declarada");

                       if (metodo.equals("global")){

                                if(tabelaSimbolos.jaContemAquelaVariavelGlobal(tabelaSimbolos.getLookahead())){
                                    if(!tabelaSimbolos.verificaGlobais(tabelaSimbolos.getLookahead())){
                                         System.out.println("Linha "+ tabelaSimbolos.getLinha() +":" + " A Variavel " + tabelaSimbolos.getLookahead() +
                                                 " já foi declarada entre as globais");
                                         ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                                    }
                                }
                            }

                        else
                        {
                        //Analisa se a variável ja foi declarada dentro do método. Se existe duas váriasveis com o mesmo nome.
                            if(!(tabelaSimbolos.verificaMetodoEMetodo(tabelaSimbolos.getLookahead(), metodo)))
                            {
                                System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                                        "foi declarada mais de uma vez no metodo " + metodo);
                                ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada");
                            }
                        //Verifica se a variavel, que esta declarada em um método, ja foi declarada como global.
                            if(!(tabelaSimbolos.verificaMetodoEGlobal(tabelaSimbolos.getLookahead()))){
                                System.out.println("Linha "+ tabelaSimbolos.getLinha() +": " +"A variável " + tabelaSimbolos.getLookahead() +
                                                    " declarada no método " + metodo + " também foi declarada como global" );
                                ErroSemantico.getInstance().getTabelaErros().add("Erro Semântico na linha " +tabelaSimbolos.getLinha() + ". Descrição: Variável já foi declarada como global");
                            }
                        }
                        tabelaSimbolos.soConsome();//Consome o identificador
                    }
                        
                    if(tabelaSimbolos.getLookahead().equals("="))
                    {
                        if(!Utils.tipoValor(tabelaSimbolos.getLookahead()).equals(tipo))
                        {
                            System.out.println("Tipos não compatíveis");
                        }
                    }
                }
            }
        }
        tabelaSimbolos.soConsome();//Consome ;
       
    }
    
    public boolean casoVetor()
    {
        tabelaSimbolos.soConsome();//Consome [
        if(!Utils.tipoValor(tabelaSimbolos.getLookahead()).equals("int"))
            return false;//Erro que não veio Int
        tabelaSimbolos.soConsome();//Consome o que tem dentro do []
        tabelaSimbolos.soConsome();//Consome ]
        return true;
    }    
}
